package org.gpp.proj1.robot.part;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.gpp.proj1.robot.modifier.Modifier;
import org.gpp.proj1.robot.part.emissor.Emissor;
import org.gpp.proj1.util.ModelFactory;
import org.gpp.proj1.util.TextureStateFactory;

import com.jme.scene.Node;
import com.jme.scene.Spatial;

/**
 * A generic robot part implementation
 *  
 * @author Paolo Victor, paolovictor@gmail.com
 */
/**
 * @author Paolo Victor, paolovictor@gmail.com
 *
 */
public class SparePart extends Node implements Part {

	private static final long serialVersionUID = 4960471530786862569L;

	/**
	 * The part's name
	 */
	protected String name;

	/**
	 * The part's type
	 */
	protected PartType type;
	
	/**
	 * The part's price on the part shop
	 */
	protected int price;
	
	/**
	 * The modifiers. May be empty
	 */
	protected List<Modifier> modifiers;
	
	/**
	 * The models that will be displayed for this part. The
	 * model name should be the same as the bone it is supposed
	 * to represent!
	 */
	protected Map<String, String> models;
	
	/**
	 * The models' textures
	 */
	protected Map<String, String> modelTextures;

	/**
	 * The part's actions
	 */
	protected List<String> actions;
	
	/**
	 * The particle emitter for this part. They are attached to a model
	 * during the particle actions
	 */
	protected List<Emissor> emissorPoints;

	/**
	 * The part's attributes, such as the defense, energy, etc
	 */
	protected Map<String, Integer> metadata;
	
	/**
	 * @param name
	 * @param type
	 * @param metadata Map with the part's attributes 
	 * @param modifiers
	 * @param models
	 * @param modelTextures 
	 * @param particleEmissors
	 * @param actions
	 */
	public SparePart( String name, PartType type, int price, Map<String, Integer> metadata, List<Modifier> modifiers, Map<String, String> models, Map<String, String> modelTextures, List<Emissor> particleEmissors, List<String> actions ) {
		this.name = name;
		this.type = type;
		this.price = price;
		this.metadata = metadata;
		this.modifiers = modifiers;
		this.models = models;
		this.actions = actions;
		this.modelTextures = modelTextures;
		
		this.emissorPoints = new LinkedList<Emissor>();
		for( Emissor emissorPoint : particleEmissors ) {
			this.emissorPoints.add( emissorPoint );
		}
	}
	
	@Override
	protected Object clone() {
		SparePart clone = new SparePart( name, type, price, metadata, modifiers, models, modelTextures, emissorPoints, actions );
		
		return clone;
	}
	
	/**
	 * @return The part's name
	 */
	public String getName() {
		return name;
	}
	
	/**
	 * @return The part's type
	 */
	public PartType getPartType() {
		return this.type;
	}

	/**
	 * @return The part's price
	 */
	public int getPrice() {
		return price;
	}

	/**
	 * @return The part's modifiers
	 */
	public List<Modifier> getModifiers() {
		return modifiers;
	}

	/**
	 * @return The model for the given bone name or null if
	 * it doesn't contain a model for such a bone
	 */
	public Spatial getModel( String modelName ) {
		if( ! models.containsKey( modelName ) ) {
			return null;
		}
		
		Spatial model = ModelFactory.getInstance().getModel( models.get( modelName ) );
		
		if( modelTextures.containsKey( modelName ) ) {
			model.setRenderState( TextureStateFactory.getInstance().getTextureState( modelTextures.get( modelName ) ) );
			model.updateRenderState();
		}
		
		return model;
	}
	
	public Set<String> getModelNames() {
		return models.keySet();
	}
	
	public Emissor getEmissor( String name ) {
		for( Emissor e : this.emissorPoints ) {
			if( e.getName().equals( name ) ) {
				return e;
			}
		}
		
		return null;
	}	

	public List<String> getActions() {
		return this.actions;
	}
}